package cmap

import (
	"github.com/pkg/errors"
	"sync/atomic"
	"unsafe"
)

type Item interface {
	link
	Key()string
	Value()interface{}
	Hash()uint64
	SetValue(value interface{})error
	Copy()Item
}
type link interface {
	Next()Item
	SetNext(item Item)error
}
type myItem struct {
	key string
	value unsafe.Pointer
	hash uint64
	next unsafe.Pointer
}

func (this *myItem)Copy()Item  {
	return NewItem(this.key,this.Value())
}
func (this *myItem)Key()string  {
	return this.key
}
func (this *myItem)Value()interface{}  {
	pointer := atomic.LoadPointer(&this.value)
	if pointer == nil{
		return nil
	}
	return *((*interface{})(pointer))
}
func (this *myItem)SetValue(value interface{})error {
	if value==nil{
		return errors.New("item set value is nil")
	}
	atomic.StorePointer(&this.value,unsafe.Pointer(&value))
	return nil
}
func (this *myItem)Hash()uint64  {
	return this.hash
}
func (this *myItem)SetNext(item Item) error {
	if item == nil{
		atomic.StorePointer(&this.next,nil)
	}
	it,ok := item.(*myItem)
	if !ok{
		return errors.New("setnext is err item is not Item")
	}
	atomic.StorePointer(&this.next,unsafe.Pointer(it))
	return nil
}
func (this *myItem)Next()Item  {
	pointer := atomic.LoadPointer(&this.next)
	if pointer == nil{
		return  nil
	}
	return (*myItem)(pointer)
}
func NewItem(key string,value interface{})Item{
	return &myItem{
		key:key,
		hash:hash(key),
		value:unsafe.Pointer(&value),
	}
}